package com.lyw.GeoLocationClient.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
import cn.bmob.v3.datatype.BmobGeoPoint;
import cn.bmob.v3.listener.FindListener;
import cn.bmob.v3.listener.SaveListener;
import cn.bmob.v3.listener.UpdateListener;
import com.baidu.location.BDLocation;
import com.baidu.mapapi.model.LatLng;
import com.baidu.trace.OnStartTraceListener;
import com.easemob.EMCallBack;
import com.easemob.chat.*;
import com.easemob.chatui.Constant;
import com.easemob.chatui.DemoHXSDKHelper;
import com.easemob.chatui.db.UserDao;
import com.easemob.chatui.domain.User;
import com.easemob.exceptions.EaseMobException;
import com.easemob.util.EMLog;
import com.easemob.util.HanziToPinyin;
import com.lyw.GeoLocationClient.App;
import com.lyw.GeoLocationClient.R;
import com.lyw.GeoLocationClient.utils.*;
import com.lyw.GeoLocationClient.bean.BmobUser;
import com.lyw.GeoLocationClient.db.GeotableDB;
import com.lyw.GeoLocationClient.db.GeotableDBHelper;
import com.lyw.GeoLocationClient.json.Geotable;
import com.lyw.GeoLocationClient.json.Poi;
import com.lyw.GeoLocationClient.json.em.EMResponse;
import com.lyw.GeoLocationClient.json.res.GeotableList;
import com.lyw.GeoLocationClient.json.res.PoiList;
import com.lyw.GeoLocationClient.json.res.Respon;
import com.lyw.GeoLocationClient.ui.GeotableItem;
import retrofit.Callback;
import retrofit.RetrofitError;
import timber.log.Timber;

import java.util.*;

public class LBSClient extends Service {

    private static final String PASSWD_COLUMN = "password";
    public static final String ADMIN = "admin";
    public static final int GEOTABLE_ID = 116429;
    public static final String DEF_IMEI = "000000000000000";

    public static final String POL_ID = "p_id";
    public static final String NAME = "name";
    public static final String UNIT = "unit";
    public static final String IMEI = "imei";
    public static final String GROUP = "group";
    public static final java.lang.String OUT_OF_GEO = "OUT_OF_GEO";
    public static final java.lang.String INTO_GEO = "INTO_GEO";
    public static final java.lang.String CMD_TASK = "CMD_TASK";
    private final Object GeotableMapLock = new Object();

    public static final int  ADMIN_TABLE_TYPE = 2;

    private static final int UPDATE_GEOFANCE_INTERVAL = 60 * 1000;
    public static LBSClient lbsClient;

//    private LiteHttpClient client;
//    private HttpAsyncExecutor asyncExecutor;
    private LBSManager mLbsManager;

    public Geotable mGeotable;
//    private LBSLocation mLBSLocation;
    private LoginCallback mLoginCallback;
//    private UICallback mUICallback;
    private boolean mLoginState;
    private boolean isAdmin;
    private int AdminGeoId;

    private GeotableDB mGeotableDB;


    private ArrayList<Geotable> mAllGeotables;
    private TraceService mTraceService;
//    private ArrayList<GeotableItem> mAllGeotables;


    public HashMap<Integer, GeotableItem> getGeotableMap() {
        return mGeotableMap;
    }

    private HashMap<Integer, GeotableItem> mGeotableMap;
    private HashMap<Integer, ArrayList<Poi>> mPoiListMap;
    private HashMap<String, ArrayList<GeotableItem>> mGroupMap;
    private List<GeotableItem> mGeotableItems;
    private LinkedList<LatLng> mGeofanceList;
    private ArrayList<UICallback> uiCallbacks;
    UserDao dao;
    BmobUserAdapter bmobUserAdapter;
    private List<BmobUser> mAdminList;
    BmobUser mUser;

    //当前所有轨迹
    private LinkedList<BDLocation> locationLinkedList;


    private static final Object daoLock = new Object();

    private IconManager mIconManager;
    @Override
    public void onCreate() {
        super.onCreate();
        lbsClient = this;
        mGeotableDB = App.getInstance().getGeotableDB();
//        client = LiteHttpClient.getInstance(this);
        bmobUserAdapter = new BmobUserAdapter(this);
//        asyncExecutor = HttpAsyncExecutor.newInstance(client);
        mLbsManager = new LBSManager(this);
        mAllGeotables = new ArrayList<Geotable>();
        mGeotableMap = new HashMap<Integer, GeotableItem>();
        mGroupMap = new HashMap<String, ArrayList<GeotableItem>>();
        mGeotableItems = new ArrayList<GeotableItem>();
        mPoiListMap = new HashMap<Integer, ArrayList<Poi>>();
        mIconManager = new IconManager();
        mGeofanceList = new LinkedList<LatLng>();
        dao = UserDao.getInstance(this);
        mTraceService = new TraceService(getApplicationContext());

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (isLogin() && !App.isAdmin()) {
            mTraceService.starTrace(mUser.getUsername(), null);
        }
        return super.onStartCommand(intent, flags, startId);
    }

    private void clear() {
        mAllGeotables.clear();
        mGeotableMap.clear();
        mGeotableItems.clear();
        mPoiListMap.clear();
//        mGeofanceList.clear();
    }

    public static LBSClient getInstance() {
        return lbsClient;
    }

    public void addContact(final String username, final String passwd, final User user) {
        bmobUserAdapter.queryBmobUser(username, new FindListener<BmobUser>() {
            @Override
            public void onSuccess(List<BmobUser> list) {
                LOG(list.size()+"");
                Runnable runnable = new Runnable() {
                    public void run() {
                        EMResponse response = App.getEmUserManager().registerUser(username, passwd);
                        LOG(response.toString());
                    }
                };
                new Thread(runnable).start();

                if (list == null || list.size() == 0) {
                    bmobUserAdapter.registerUser(username, passwd,
                            false, user.getPol_id(),
                            user.getDisplayName(), user.getUnit(),
                            user.get_group(), user.getImei(), new SaveListener() {
                                @Override
                                public void onSuccess() {
                                    LOG("create table " + username + " success");
                                    dao.saveContact(user);
                                    App.getInstance().getContactList().put(username, user);

                                    callbackUiChange();

                                    LOG("add friend owner " + App.getInstance().getUserName() + " " + username);
                                    App.getEmUserManager().addFriend(username, App.getInstance().getUserName());
                                    try {
                                        EMContactManager.getInstance().addContact(username, "add by admin");
                                        T.showShort(getInstance(), getResources().getString(R.string.add_user_success));
                                    } catch (EaseMobException e) {
                                        e.printStackTrace();
                                    }

                                    if (mTraceService != null) {
                                        mTraceService.addEntity(username, "name=" + user.getDisplayName(), null);
                                    }
                                }

                                @Override
                                public void onFailure(int i, String s) {
                                    //注册失败
                                    T.showShort(getInstance(), getResources().getString(R.string.add_contact_failed));
                                    return;
                                }
                            });
                } else {
                    T.showShort(getInstance(), getResources().getString(R.string.has_same_user));
                }
            }

            @Override
            public void onError(int i, String s) {
                //注册失败
                T.showShort(getInstance(), getResources().getString(R.string.add_contact_failed));
                return;
            }
        });

    }


//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    // 调用sdk注册方法
////            EMChatManager.getInstance().createAccountOnServer(username, passwd);
//                    EMResponse response = App.getEmUserManager().registerUser(username, passwd);
//                    Timber.e(response.toString());
//
//                    mLbsManager.createGeotable(username, passwd, new Callback<Respon>() {
//                        @Override
//                        public void success(Respon respon, retrofit.client.Response response) {
//                            LOG(respon.status + " " + respon.message);
//                            if (respon.status == 0) {
//                                user.setUsername(username);
//                                user.setGeo_id(respon.id);
//
//                                mLbsManager.createTableProp(respon.id, GeotableDBHelper.POL_ID, user.getPol_id(), responseHandler);
//                                mLbsManager.createTableProp(respon.id, GeotableDBHelper.NAME, user.getNick(), responseHandler);
//                                mLbsManager.createTableProp(respon.id, GeotableDBHelper.UNIT, user.getUnit(), responseHandler);
//                                mLbsManager.createTableProp(respon.id, GeotableDBHelper.IMEI, user.getImei(), responseHandler);
//                                mLbsManager.createTableProp(respon.id, GeotableDBHelper.GROUP, user.get_group(), responseHandler);
////                                mLbsManager.createTableProp(respon.id, GeotableDBHelper.PASSWORD, passwd, responseHandler);
//
//                                LOG("create table " + username + " success" + " id " + respon.id);
//                                dao.saveContact(user);
//                                App.getInstance().getContactList().put(username, user);
//
//                                callbackUiChange();
//
//                                LOG("add friend owner " + App.getInstance().getUserName() + " " + username);
//                                App.getEmUserManager().addFriend(username, App.getInstance().getUserName());
//                                try {
//                                    EMContactManager.getInstance().addContact(username, "add admin");
//                                } catch (EaseMobException e) {
//                                    e.printStackTrace();
//                                }
//
//                                T.showShort(getInstance(), getResources().getString(R.string.add_user_success));
//
//                            } else {
//                                T.showShort(getInstance(), getResources().getString(R.string.add_contact_failed));
//                            }
//                        }
//
//                        @Override
//                        public void failure(RetrofitError retrofitError) {
//                            T.showShort(getInstance(), getResources().getString(R.string.add_contact_failed));
//                        }
//                    });
//                } catch (Exception e) {
//
//                }
//            }
//        }).start();



//    public void modifyProp(final int geotable_id, final String key, final String value) {
//        mLbsManager.findPoi(geotable_id, key, new HttpResponseHandler() {
//            @Override
//            protected void onSuccess(Response res, HttpStatus status, NameValuePair[] headers) {
//                PoiList respon = res.getObject(PoiList.class);
//
//                if (respon != null && respon.pois != null && respon.pois.size() > 0) {
//                    LOG("find poi " + respon.toString());
//                    mLbsManager.modifyPoi(geotable_id, respon.pois.get(0).getId(), value, new HttpResponseHandler() {
//                        @Override
//                        protected void onSuccess(Response res, HttpStatus status, NameValuePair[] headers) {
//                            Respon p = res.getObject(Respon.class);
//                            if (p.status == 0) {
//                                LOG("modify success");
//                                GeotableItem item = getGeotableMap().get(geotable_id);
//
//                                if (item != null) {
//
//                                    mGeotableDB.update(setGeotableItemProp(item, key, value));
//                                    LOG("modify final item " + item);
//
//                                    loadDataBaseTable();
//                                    LOG("NOW UPDATE");
//                                    callbackUiChange();
//                                }
//                            }
//                        }
//
//                        @Override
//                        protected void onFailure(Response res, HttpException e) {
//
//                        }
//                    });
//
//
//                }
//            }
//
//            @Override
//            protected void onFailure(Response res, HttpException e) {
//
//            }
//        });
//
//
//    }

    private GeotableItem setGeotableItemProp(GeotableItem item, String key, String value) {
        if (item == null || key == null || value == null) {
            return null;
        }
        if (GeotableDBHelper.GEO_TITLE.equals(key)) {
            item.setTitle(value);
        } else if (GeotableDBHelper.POL_ID.equals(key)) {
            item.setPolId(value);
        } else if (GeotableDBHelper.PUSH_ID.equals(key)) {
            item.setPushID(Integer.valueOf(value));
        } else if (GeotableDBHelper.PUSH_CHANNEL.equals(key)) {
            item.setPushChannel(Integer.valueOf(value));
        } else if (GeotableDBHelper.NAME.equals(key)) {
            item.setName(value);
        } else if (GeotableDBHelper.UNIT.equals(key)) {
            item.setUnit(value);

        } else if (GeotableDBHelper.GROUP.equals(key)) {
            item.setGroup(value);
        } else if (GeotableDBHelper.IMEI.equals(key)) {
            item.setGroup(value);
        }
        return item;
    }

//    public void createGeotable(String name, final String pwd) {
//        mUserName = name;
//        mPasswd = pwd;
//        mLbsManager.createGeotable(name, pwd, new Callback<Respon>() {
//            @Override
//            public void success(Respon respon, retrofit.client.Response response) {
//                LOG(respon.status + " " + respon.message);
//                if (respon.status == 0) {
//                    LOG("create table success");
//
//                    setPasswd(respon.id, pwd);
//                } else {
//                    if (mLoginCallback != null) {
//                        mLoginCallback.onRegister(false);
//                    }
//                }
//
//            }
//
//            @Override
//            public void failure(RetrofitError retrofitError) {
//                if (mLoginCallback != null) {
//                    mLoginCallback.onRegister(false);
//                }
//            }
//        });
//    }

    public void loadDataBaseTable() {
        if (mGeotableDB != null) {
            synchronized (GeotableMapLock) {

                mGeotableItems.clear();
                mGroupMap.clear();
                mGeotableItems.addAll(mGeotableDB.getTables());
                for (GeotableItem geotableItem : mGeotableItems) {
                    mGeotableMap.put(geotableItem.getGeoId(), geotableItem);
                    addGeotableToGroup(geotableItem);
                }
                LOG("load form db " + mGeotableItems.size());
            }
        }
    }

    private void addGeotableToGroup(GeotableItem item) {
        String group = "";
        if (!StringUtils.isNullOrEmpty(item.getGroup())) {
            group = item.getGroup();
        }
        ArrayList<GeotableItem> list = mGroupMap.get(group);
        if ( list == null) {
            list = new ArrayList<GeotableItem>();
            list.add(item);
            mGroupMap.put(group, list);
        } else {
            list.add(item);
            mGroupMap.put(group, list);
        }
    }

    private void loadNetworkTable() {
//        listGeotable(new HttpResponseHandler() {
//            @Override
//            protected void onSuccess(Response res, HttpStatus status, NameValuePair[] headers) {
//                GeotableList geotableList = res.getObject(GeotableList.class);
//                if (geotableList.geotables != null && geotableList.geotables.size() > 0) {
//                    LOG("loadNetworkTable " + geotableList.geotables.size());
//                    setAllGeotables(geotableList.geotables);
//                }
////                    mHandler.post(new UpdateListRun());
//            }
//
//            @Override
//            protected void onFailure(Response res, HttpException e) {
//
//            }
//        });
    }

    public void loadTableList() {
//        loadDataBaseTable();
//        if (mGeotableItems == null ||
//                mGeotableItems.size() == 0) {// database is empty
//            loadNetworkTable();
//        }
    }
//
//    public void listGeotable(HttpResponseHandler httpResponseHandler) {
//        mLbsManager.ListGeotable(httpResponseHandler);
//    }


    private void requestLogin(final String username, final String passwd) {
        LOG("requestLogin " + username + " " + passwd);
        bmobUserAdapter.login(username, passwd, new FindListener<BmobUser>() {
            @Override
            public void onSuccess(List<BmobUser> list) {
                if (list == null || list.size() == 0) {
                    Timber.e("cannot find user " + username);
                    if (mLoginCallback != null) {
                        mLoginCallback.onLogin(false);
                    }
                } else {
                    mUser = list.get(0);

//                    mPasswd = passwd;
                    LOG("Login success");
                    mLoginState = true;

                    App.setIsAdmin(mUser.getIsAdmin());

                    String imei = mUser.getImei();
                    if (verifyImei(imei)) {
                        if (mUser.getIsAdmin()) {
//                            startLocation();

                            loginEASE(username, passwd, mUser.getName());
                        } else {
                            //开始定位
                            startLocation();
                            setGeofanceSchedule();

                            loginEASE(username, passwd, mUser.getName());
                            getAdminList();
                            getGeofance();
                        }
                    } else {
                        Timber.e("User imei is " + mUser.getImei() + "app is " + App.getImei());
                        Timber.e("--- Check Imei failed");
                        if (mLoginCallback != null) {
                            mLoginCallback.onLogin(false);
                        }
                    }
                }
            }

            @Override
            public void onError(int i, String s) {
                Timber.e(s);
                if (mLoginCallback != null) {
                    mLoginCallback.onLogin(false);
                }
            }
        });
//        listTable(name, new Callback<GeotableList>() {
//            @Override
//            public void success(GeotableList geotableList, retrofit.client.Response response) {
//                if (geotableList == null) {
//                    if (mLoginCallback != null) {
//                        mLoginCallback.onLogin(false);
//                    }
//                    return;
//                }
//                if (geotableList.geotables != null && geotableList.geotables.size() > 0) {
//                    LOG(Arrays.toString(geotableList.geotables.toArray()));
//                    mGeotable = geotablipeList.geotables.get(0);
//                    mUserName = name;
//                    LOG("get Geo table " + name);
//                    verifyPasswd(mGeotable.id, passwd);
//                } else {
//                    LOG("this table not find");
//                    if (mLoginCallback != null) {
//                        mLoginCallback.onLogin(false);
//                    }
//                }
//            }
//
//            @Override
//            public void failure(RetrofitError retrofitError) {
//                if (mLoginCallback != null) {
//                    mLoginCallback.onLogin(false);
//                }
//            }
//        });
    }

    private boolean verifyImei(String imei) {
        if (imei.equals(DEF_IMEI)) {
            return true;
        }

        return imei.equals(App.getImei());
    }

    private void getAdminList() {
        bmobUserAdapter.queryAdmin(new FindListener<BmobUser>() {

            @Override
            public void onSuccess(List<BmobUser> list) {
                mAdminList = list;
            }

            @Override
            public void onError(int i, String s) {

            }
        });
    }

    private void getGeoLocationList() {

    }

    private void loginEASE(final String username, final String passwd, final String nick) {
        //login EASE
        LOG("loginEASE");
        if (DemoHXSDKHelper.getInstance().isLogined()) {
            EMGroupManager.getInstance().loadAllGroups();
            EMChatManager.getInstance().loadAllConversations();

            if (mLoginCallback != null) {
                mLoginCallback.onLogin(true);
            } else {
                LOG("ui is null!");
            }
            App.getInstance().setUserName(username);
            App.getInstance().setPassword(passwd);
        } else {
            loginHx(username, passwd);
            App.getSpUtil().setAdminRegisted(false);
        }
    }

    public void listTable(String name, Callback<GeotableList> cb) {
        mLbsManager.listTable(name, cb);
    }

//    public void listGeotable(final String name, final String passwd) {
//        mLbsManager.ListGeotable(name, passwd,  new HttpResponseHandler() {
//            @Override
//            protected void onSuccess(Response res, HttpStatus status, NameValuePair[] headers) {
//                GeotableList geotableList = res.getObject(GeotableList.class);
//                if (geotableList == null) {
//                    if (mLoginCallback != null) {
//                        mLoginCallback.onLogin(false);
//                    }
//                    return;
//                }
//                if (geotableList.geotables != null && geotableList.geotables.size() > 0) {
//                    LOG(Arrays.toString(geotableList.geotables.toArray()));
//                    LOG("set Geo table");
//                    mGeotable = geotableList.geotables.get(0);
//                    mUserName = name;
//                    verifyPasswd(mGeotable.id, passwd);
//                } else {
//                    LOG("this table not find");
//                    if (mLoginCallback != null) {
//                        mLoginCallback.onLogin(false);
//                    }
//                }
//            }
//
//            @Override
//            protected void onFailure(Response res, HttpException e) {
//                if (mLoginCallback != null) {
//                    mLoginCallback.onLogin(false);
//                }
//            }
//        });
//
////        return client.get(LBSUrl.LIST_GEOTABLE, req, GeotableList.class);
//    }

//    public void updatePoiListMap(ArrayList<GeotableItem> geotableItems, HttpResponseHandler httpResponseHandler) {
//
//
//    }



//    private void setPasswd(final int geotableID, final String passwd) {
//        CreateColumnReq createColumnReq = new CreateColumnReq(geotableID, PASSWD_COLUMN, passwd);
//        Request request = new Request(LBSUrl.CREATE_COLUMN);
//        request.setMethod(HttpMethod.Post);
//        request.setParamModel(createColumnReq);
//
//        asyncExecutor.execute(request,new HttpResponseHandler() {
//            @Override
//            protected void onSuccess(Response res, HttpStatus status, NameValuePair[] headers) {
//                Respon respon = res.getObject(Respon.class);
//                if (respon!= null && respon.status == 0) {
//                    LOG("set passwd success");
//                    if (mLoginCallback != null) {
//                        mLoginCallback.onRegister(true);
//                    }
//                } else {
//                    delGeotable(geotableID);
//                    if (mLoginCallback != null) {
//                        mLoginCallback.onRegister(false);
//                    }
//                }
//            }
//
//            @Override
//            protected void onFailure(Response res, HttpException e) {
//                delGeotable(geotableID);
//                if (mLoginCallback != null) {
//                    mLoginCallback.onRegister(false);
//                }
//            }
//        } );
//
//    }


    public void setPushId(final String pushId, final String pushChannel) {
        if (isLogin()) {

            mLbsManager.createTableProp(mGeotable.id, GeotableDBHelper.PUSH_ID, pushId, responseHandler);
            mLbsManager.createTableProp(mGeotable.id, GeotableDBHelper.PUSH_CHANNEL, pushChannel, responseHandler);
        }
    }


    private Timer mUpdateGeofanceTimer;
    private void setGeofanceSchedule() {
        if (mUpdateGeofanceTimer != null) {
            mUpdateGeofanceTimer.cancel();
            mUpdateGeofanceTimer = null;
        }
        mUpdateGeofanceTimer = new Timer();
        mUpdateGeofanceTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                getGeofance();
            }
        },0, UPDATE_GEOFANCE_INTERVAL);
    }

    public void getGeofance() {
        mGeofanceList.clear();
        if (mUser.getGeofance() != null) {
            ArrayList<BmobGeoPoint> geofance = mUser.getGeofance();
            for (int i = 0; i < geofance.size(); i++) {
                BmobGeoPoint poi = geofance.get(i);
                LatLng latLng = new LatLng(poi.getLatitude(), poi.getLongitude());
                mGeofanceList.add(latLng);
            }
        }
    }

//    private void getLBSGeofancePois(int geotable_id) {
//        mLbsManager.getPoiList(geotable_id, new HttpResponseHandler() {
//            @Override
//            protected void onSuccess(Response res, HttpStatus status, NameValuePair[] headers) {
//                PoiList respon = res.getObject(PoiList.class);
//                if (respon != null && respon.status == 0) {
//                    if (respon.pois != null && respon.pois.size() > 2) {
//                        mGeofanceList.clear();
//                        LOG("get getLBSGeofancePois " + respon.pois.size());
//                        for (Poi p : respon.pois) {
//                            double[] loc = p.getLocation();
//                            LatLng latLng = new LatLng(loc[1], loc[0]);
//                            mGeofanceList.add(latLng);
//                        }
//                    }
//                }
//            }
//
//            @Override
//            protected void onFailure(Response res, HttpException e) {
//
//            }
//        });
//    }

    public void saveGeofance(BmobUser user, ArrayList<BmobGeoPoint> geofance) {
        Timber.d("saveGeofance");
        user.setGeofance(geofance);

        bmobUserAdapter.updateUser(user, new UpdateListener() {
            @Override
            public void onSuccess() {
                Timber.d("success");
            }

            @Override
            public void onFailure(int i, String s) {
                Timber.d("onFailure " + i + " " + s);

            }
        });
    }

//    public void saveGeofancePois(LinkedList<LatLng> list) {
//        if (!isAdminPermisition()) {
//            return;
//        }
//
//        setGeofanceList(list);
//
//
//        final int geotable_id = mGeotable.id;
//        mLbsManager.getPoiList(geotable_id, new HttpResponseHandler() {
//            @Override
//            protected void onSuccess(Response res, HttpStatus status, NameValuePair[] headers) {
//                PoiList respon = res.getObject(PoiList.class);
//                if (respon != null && respon.status == 0) {
//                    LOG("first, del pois ");
//                    delPois(geotable_id, respon.pois);
////                    delPois(geotable_id, respon.pois, delPoisHandle);
//                }
//            }
//
//            @Override
//            protected void onFailure(Response res, HttpException e) {
//
//            }
//        });
//
//    }

//    private HttpResponseHandler delPoisHandle = new HttpResponseHandler() {
//        @Override
//        protected void onSuccess(Response res, HttpStatus status, NameValuePair[] headers) {
//            DelPoisRespon respon = res.getObject(DelPoisRespon.class);
//            if (respon != null && respon.status == 21) {
//                LOG("second, upload geofance");
//                uploadGeofance();
//            }
//        }
//
//        @Override
//        protected void onFailure(Response res, HttpException e) {
//
//        }
//    };

//    private LinkedList<LatLng> mTmpGeofanceList;
//    private void uploadGeofance() {
//        if (mTmpGeofanceList == null) {
//            mTmpGeofanceList = new LinkedList<LatLng>();
//        } else {
//            mTmpGeofanceList.clear();
//        }
//        mTmpGeofanceList.addAll(mGeofanceList);
//
//        if (mTmpGeofanceList.size() > 0) {
//            LatLng latLng = mTmpGeofanceList.getFirst();
//            mTmpGeofanceList.remove(latLng);
//            createPoi(latLng.latitude, latLng.longitude,
//                    uploadGeofanceHandle
//            );
//        }
//
//    }

    //为了保证顺序, 百度地图根据点的顺序构造多边形.
//    HttpResponseHandler uploadGeofanceHandle = new HttpResponseHandler() {
//        @Override
//        protected void onSuccess(Response res, HttpStatus status, NameValuePair[] headers) {
//            if (mTmpGeofanceList.size() > 0) {
//                LatLng latLng = mTmpGeofanceList.getFirst();
//                mTmpGeofanceList.remove(latLng);
//                createPoi(latLng.latitude, latLng.longitude,
//                        uploadGeofanceHandle);
//            }
//        }
//
//        @Override
//        protected void onFailure(Response res, HttpException e) {
//
//        }
//    };

//    private void delPois(int geotable_id, ArrayList<Poi> list) {
//        if (list != null && list.size() > 0) {
//            LOG("will clear " + list.size() + " pois one by one");
//            for (Poi poi : list) {
//                delPoi(poi.getId(), geotable_id);
//            }
//        }
//
//        //TODO 需要添加timmer检查是否真正成功删除所有poi
//        uploadGeofance();
//    }

//    private void delPois(int geotable_id, ArrayList<Poi> list, HttpResponseHandler handler) {
//        if (list != null && list.size() > 0) {
//            LOG("will clear " + list.size() + " pois");
//            String allPoi = "";
//            for (Poi poi : list) {
//                allPoi += poi.getId();
//            }
//
//            DelPoisReq req = new DelPoisReq();
//            req.ids = allPoi;
//            req.geotable_id = geotable_id;
//
//            Request request = new Request(LBSUrl.DEL_POIS);
//            request.setMethod(HttpMethod.Post);
//            request.setParamModel(req);
//            asyncExecutor.execute(request, handler);
//        } else {
//            LOG("old geofance is empty , update now");
//            uploadGeofance();
//        }
//    }

//    private void delPoi(int poi_id, int geotable_id) {
//        DelPoiReq req = new DelPoiReq(poi_id, geotable_id);
//        Request request = new Request(LBSUrl.DEL_POIS);
//        request.setMethod(HttpMethod.Post);
//        request.setParamModel(req);
////        asyncExecutor.execute(request, responseHandler);
//    }

//    private void delGeotable(int geotable_id) {
//        DelGeotableReq req = new DelGeotableReq();
//        req.id = geotable_id;
//
//        Request request = new Request(LBSUrl.DELECT_GEOTABLE);
//        request.setMethod(HttpMethod.Post);
//        request.setParamModel(req);
////        asyncExecutor.execute(request, responseHandler);
//    }

    private void verifyPasswd(final int geotableID, final String passwd) {
//        mLbsManager.listPoi(geotableID, null, new Callback<PoiList>() {
//            @Override
//            public void success(PoiList poiList, retrofit.client.Response response) {
//                ArrayList<Poi> ps = poiList.pois;
////                LOG("list all poi " + ps.size());
//                if (ps != null && ps.size() > 0) {
//                    mPasswd = passwd;
//                    LOG("Login success");
//                    mLoginState = true;
//
//                    if (App.isAdmin()) {
//                        isAdmin = true;
//                        AdminGeoId = geotableID;
//                        stopLocation();
//                        mPushMessageManager.start();
//                    } else {
//                        //verify imei
//                        if (verifyImei(ps)) {
//                            //开始定位
//                            startLocation();
//                            setGeofanceSchedule();
//                        } else {
//                            Timber.e("--- Check Imei failed");
//                            if (mLoginCallback != null) {
//                                mLoginCallback.onLogin(false);
//                            }
//                            return;
//                        }
//                    }
//                    //login EASE
//                    if (DemoHXSDKHelper.getInstance().isLogined()) {
//                        EMGroupManager.getInstance().loadAllGroups();
//                        EMChatManager.getInstance().loadAllConversations();
//
//                        if (mLoginCallback != null) {
//                            mLoginCallback.onLogin(true);
//                            return;
//                        } else {
//                            LOG("ui is null!");
//                            return;
//                        }
//
//                    } else {
//                        loginHx(mUserName, passwd);
//                        return;
//                    }
//
//                }
//
//                if (mLoginCallback != null) {
//                    mLoginCallback.onLogin(false);
//                }
//            }
//
//            @Override
//            public void failure(RetrofitError retrofitError) {
//                if (mLoginCallback != null) {
//                    mLoginCallback.onLogin(false);
//                }
//            }
//        });
    }

//    private boolean verifyImei(String name, FindListener<BmobChatUser> listener) {
//        LOG("verify imei " + App.getImei());
//        bmobUserAdapter.queryBmobUser(name, new FindListener<BmobChatUser>() {
//            @Override
//            public void onSuccess(List<BmobChatUser> list) {
//                if ()
//            }
//
//            @Override
//            public void onError(int i, String s) {
//
//            }
//        });
//        return false;
//    }

    private void loginHx(final String name, final String passwd) {
        EMChatManager.getInstance().login(name, passwd, new EMCallBack() {

            @Override
            public void onSuccess() {
                App.getInstance().setUserName(name);
                App.getInstance().setPassword(passwd);

                try {
                    // ** 第一次登录或者之前logout后再登录，加载所有本地群和回话
                    // ** manually load all local groups and
                    // conversations in case we are auto login
                    EMGroupManager.getInstance().loadAllGroups();
                    EMChatManager.getInstance().loadAllConversations();
                    EMChatManager.getInstance().getAccessToken();
                    //处理好友和群组
                    processContactsAndGroups(null);
                    loginSuccess();

                    boolean updatenick = EMChatManager.getInstance().updateCurrentUserNick(App.currentUserNick.trim());
                    if (!updatenick) {
                        Log.e("LoginActivity", "update current user nick fail");
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    //取好友或者群聊失败，不让进入主页面

                    App.getInstance().logout(null);
                    loginFailed();
                    return;
                }
            }

            @Override
            public void onError(int i, String s) {
                loginFailed();
            }

            @Override
            public void onProgress(int i, String s) {

            }
        });
    }

    private void loginFailed() {
        if (mLoginCallback != null) {
            mLoginCallback.onLogin(false);
        }
    }

    private void loginSuccess() {
        if (mLoginCallback != null) {
            mLoginCallback.onLogin(true);
        }
    }

    public void setContactPropChangeListener(ContactPropChange contactPropChangeListener) {
        this.contactPropChangeListener = contactPropChangeListener;
    }

    public List<BmobUser> getmAdminList() {
        return mAdminList;
    }

    public interface ContactPropChange {
        void onChange(User user);
    }

    private ContactPropChange contactPropChangeListener;


    private void processContactsAndGroups(final ContactPropChange change) throws EaseMobException {
        // demo中简单的处理成每次登陆都去获取好友username，开发者自己根据情况而定
        List<String> usernames = EMContactManager.getInstance().getContactUserNames();
        LOG("get contact names " + usernames.toString());
        EMLog.d("roster", "contacts size: " + usernames.size());

        Map<String, User> userlist = App.getInstance().getContactList();
        if (userlist != null && userlist.size() > 0) {
            for (String username : usernames) {
                if (userlist.get(username) != null) {
                    continue;
                }
                User user = new User();
                user.setUsername(username);
                setUserHearder(username, user);
                userlist.put(username, user);
            }
            if (userlist.get(Constant.NEW_FRIENDS_USERNAME) == null) {
                // 添加user"申请与通知"
                User newFriends = new User();
                newFriends.setUsername(Constant.NEW_FRIENDS_USERNAME);
                String strChat = getResources().getString(R.string.Application_and_notify);
                newFriends.setNick(strChat);

                userlist.put(Constant.NEW_FRIENDS_USERNAME, newFriends);
            }

            if (userlist.get(Constant.GROUP_USERNAME) == null) {
                // 添加"群聊"
//                User groupUser = new User();
//                String strGroup = getResources().getString(R.string.group_chat);
//                groupUser.setUsername(Constant.GROUP_USERNAME);
//                groupUser.setNick(strGroup);
//                groupUser.setHeader("");
//                userlist.put(Constant.GROUP_USERNAME, groupUser);
            }
        } else {
            userlist = new HashMap<String, User>();
            for (String username : usernames) {
                User user = new User();
                user.setUsername(username);
                setUserHearder(username, user);
                userlist.put(username, user);
            }

            // 添加user"申请与通知"
            User newFriends = new User();
            newFriends.setUsername(Constant.NEW_FRIENDS_USERNAME);
            String strChat = getResources().getString(R.string.Application_and_notify);
            newFriends.setNick(strChat);

            userlist.put(Constant.NEW_FRIENDS_USERNAME, newFriends);

            // 添加"群聊"
//            User groupUser = new User();
//            String strGroup = getResources().getString(R.string.group_chat);
//            groupUser.setUsername(Constant.GROUP_USERNAME);
//            groupUser.setNick(strGroup);
//            groupUser.setHeader("");
//            userlist.put(Constant.GROUP_USERNAME, groupUser);
        }

        // 存入db
        List<User> users = new ArrayList<User>(userlist.values());
        synchronized (daoLock) {
            dao.saveContactList(users);
        }

        // 存入内存
        App.getInstance().setContactList(userlist);

        //获取黑名单列表
        List<String> blackList = EMContactManager.getInstance().getBlackListUsernamesFromServer();
        //保存黑名单
        EMContactManager.getInstance().saveBlackList(blackList);

        // 获取群聊列表(群聊里只有groupid和groupname等简单信息，不包含members),sdk会把群组存入到内存和db中
        EMGroupManager.getInstance().getGroupsFromServer();


        new Thread(new Runnable() {
            @Override
            public void run() {
                if (change == null && contactPropChangeListener != null) {
                    getUsersProps(contactPropChangeListener);
                } else {
                    getUsersProps(change);
                }
            }
        }).start();
    }



    /**
     * 获取所有联系人信息
     */
    public void getUsersProps(final ContactPropChange change) {
        LOG("getUsersProps");
        List<User> users = new ArrayList<User>(App.getInstance().getContactList().values());
        LOG("users size " + users.size());

        for (int i = 0; i < users.size(); i++) {
            final User user = users.get(i);
            if (user.getUsername().equals(Constant.NEW_FRIENDS_USERNAME)
                    || user.getUsername().equals(Constant.GROUP_USERNAME)) {
                continue;
            }

            getUserProp(user.getUsername(), change);
//            mLbsManager.listPoi(user.getGeo_id(), user.getUsername(), new Callback<PoiList>() {
//                @Override
//                public void success(PoiList poiList, retrofit.client.Response response) {
//                    if (poiList != null && poiList.pois != null && poiList.pois.size() > 0) {
//                        for (int j = 0; j < poiList.pois.size(); j++) {
//                            Poi p = poiList.pois.get(j);
//                            if (p.getTitle().equals(GeotableDBHelper.POL_ID)) {
//                                user.setPol_id(p.getAddress());
//                            } else if (p.getTitle().equals(GeotableDBHelper.NAME)) {
//                                user.setNick(p.getAddress());
//                                setUserHearder(user.getUsername(), user);
//                            } else if (p.getTitle().equals(GeotableDBHelper.UNIT)) {
//                                user.setUnit(p.getAddress());
//                            } else if (p.getTitle().equals(GeotableDBHelper.IMEI)) {
//                                user.setImei(p.getAddress());
//                            } else if (p.getTitle().equals(GeotableDBHelper.GROUP)) {
//                                user.set_group(p.getAddress());
//                            }
//                        }
//                        synchronized (daoLock) {
//                            dao.saveContact(user);
//                        }
//
//                        if (change != null) {
//                            change.onChange(user);
//                        }
//                    }
//                }
//
//                @Override
//                public void failure(RetrofitError retrofitError) {
//
//                }
//            });
        }
    }

    public void getUserProp(final String username, final ContactPropChange change) {
        bmobUserAdapter.queryBmobUser(username, new FindListener<BmobUser>() {
            @Override
            public void onSuccess(List<BmobUser> list) {
                if (list != null && list.size() > 0) {
                    User user = App.getInstance().getContactList().get(username);
                    BmobUser bmobUser = list.get(0);
                    Timber.d("get userprop " + bmobUser);
                    if (user != null) {
                        user.setPol_id(bmobUser.getPolId());
                        user.setNick(bmobUser.getName());
                        setUserHearder(bmobUser.getName(), user);
                        user.setUnit(bmobUser.getUnit());
                        user.setImei(bmobUser.getImei());
                        user.set_group(bmobUser.getGroup());

                        synchronized (daoLock) {
                            dao.saveContact(user);
                        }

                        if (change != null) {
                            Timber.d("onchange " + bmobUser);

                            change.onChange(user);
                        } else {
                            if (contactPropChangeListener != null) {
                                contactPropChangeListener.onChange(user);
                            }
                        }
                    }
                }
            }

            @Override
            public void onError(int i, String s) {

            }
        });
    }


    /**
     * 设置hearder属性，方便通讯中对联系人按header分类显示，以及通过右侧ABCD...字母栏快速定位联系人
     *
     * @param username
     * @param user
     */
    protected void setUserHearder(String username, User user) {
        String headerName = null;
        if (!TextUtils.isEmpty(user.getNick())) {
            headerName = user.getNick();
        } else {
            headerName = user.getUsername();
        }
        if (username.equals(Constant.NEW_FRIENDS_USERNAME)) {
            user.setHeader("");
        } else if (Character.isDigit(headerName.charAt(0))) {
            user.setHeader("#");
        } else {
            user.setHeader(HanziToPinyin.getInstance().get(headerName.substring(0, 1)).get(0).target.substring(0, 1).toUpperCase());
            char header = user.getHeader().toLowerCase().charAt(0);
            if (header < 'a' || header > 'z') {
                user.setHeader("#");
            }
        }
    }

    private void startLocation() {
        isOutOfGeofance = false;
        LOG("star location for user " + mUser.getUsername());
        mTraceService.setLocationCallback(new LocationCallback() {
            @Override
            public void onReceiveLocation(BDLocation lo) {
                setLocation(lo);
            }
        });

        mTraceService.starTrace(mUser.getUsername(), new OnStartTraceListener() {
            // 开启轨迹服务回调接口（arg0 : 消息编码，arg1 : 消息内容，详情查看类参考）
            public void onTraceCallback(int arg0, String arg1) {
                LOG("开启轨迹服务回调接口消息 [消息编码 : " + arg0 + "，消息内容 : " + arg1 + "]");
            }

            // 轨迹服务推送接口（用于接收服务端推送消息，arg0 : 消息类型，arg1 : 消息内容，详情查看类参考）
            public void onTracePushCallback(byte arg0, String arg1) {
                LOG("轨迹服务推送接口消息 [消息类型 : " + arg0 + "，消息内容 : " + arg1 + "]");
            }
        });
//        LBSLocation.getInstance(getApplication(), new LocationCallback() {
//            @Override
//            public void onReceiveLocation(BDLocation lo) {
//                setLocation(lo);
//            }
//        });
    }

    public TraceService getTraceService() {
        return mTraceService;
    }

    public void restartLocation() {
        if (mTraceService != null) {
            mTraceService.starTrace(mUser.getUsername(), null);

        }
    }


    public void stopLocation() {
//        if (mLBSLocation != null) {
//            mLBSLocation.stop();
//        }
        if (mTraceService != null) {
            mTraceService.stopTrace(null);
        }
    }

    private boolean isOutOfGeofance;
    public void setLocation(BDLocation currlocation) {
        if (currlocation != null) {
            LOG("setLocation + " + currlocation.getLatitude() + " " + currlocation.getLongitude());
            if (uiCallbacks != null) {
                for (int i = 0; i < uiCallbacks.size(); i++) {
                    UICallback callback = uiCallbacks.get(i);
                    if (callback != null) {
                        callback.onReceiveLocation(currlocation);
                    }
                }
            }

            if (locationLinkedList == null) {
                locationLinkedList = new LinkedList<>();
            }
            locationLinkedList.add(currlocation);

//            if (isLogin() && App.isAdmin()) {
//                stopLocation();
//                return;
//            }
//            //send to LBS
//            if (lbsClient != null) {
//                LOG("send to LBS");
//                createPoi(currlocation.getLatitude(), currlocation.getLongitude());
//                if (uiCallbacks != null) {
//                    for (int i = 0; i < uiCallbacks.size(); i++) {
//                        UICallback callback = uiCallbacks.get(i);
//                        if (callback != null) {
//                            callback.onReceiveLocation(currlocation);
//                        }
//                    }
//                }
//                if (!isPointInGeofance(currlocation.getLatitude(), currlocation.getLongitude())) {
//                    LOG("notice , out of geofance");
//                    if (!isOutOfGeofance) {
//                        sendOutOfGeofanceMessage();
//                        NotificationHelper.getInstance(this).notifyOutOfGeofance(0);
//                    }
//                    isOutOfGeofance = true;
//
//                } else {
//                    if (isOutOfGeofance) {
//                        sendIntoGeofanceMessage();
//                        NotificationHelper.getInstance(this).removeNotify(0);
//                    }
//                    isOutOfGeofance = false;
//                }
//
//            }
        }
    }

    EMCallBack emCallBack = new EMCallBack() {
        @Override
        public void onSuccess() {
            Timber.d("");
        }

        @Override
        public void onError(int i, String s) {
            Timber.d(s);
        }

        @Override
        public void onProgress(int i, String s) {
//                    Timber.d("");
        }
    };

    private void sendOutOfGeofanceMessage() {

        for (BmobUser toUser : mAdminList) {
            final EMMessage cmdMessage = EMMessage.createSendMessage(EMMessage.Type.CMD);
            cmdMessage.setReceipt(toUser.getUsername());
            CmdMessageBody cmdMessageBody = new CmdMessageBody(OUT_OF_GEO);
            cmdMessage.addBody(cmdMessageBody);
            EMChatManager.getInstance().sendMessage(cmdMessage, emCallBack);

            EMMessage message = EMMessage.createSendMessage(EMMessage.Type.LOCATION);
            BDLocation location = getCurrLocation();
            LocationMessageBody locBody = new LocationMessageBody(location.getAddrStr(), location.getLatitude(),
                    location.getLongitude());
            message.addBody(locBody);
            message.setReceipt(toUser.getUsername());
            EMChatManager.getInstance().sendMessage(message, emCallBack);

            EMMessage txtmessage = EMMessage.createSendMessage(EMMessage.Type.TXT);
            String content = getString(R.string.out_of_geofance) + ", " + String.format(getString(R.string.notifyItemMsg), location.getAddrStr());
            TextMessageBody txtBody = new TextMessageBody(content);
            txtmessage.addBody(txtBody);
            txtmessage.setReceipt(toUser.getUsername());
            EMChatManager.getInstance().sendMessage(txtmessage, emCallBack);


        }
    }

    private void sendIntoGeofanceMessage() {

        for (BmobUser toUser : mAdminList) {
            final EMMessage cmdMessage = EMMessage.createSendMessage(EMMessage.Type.CMD);
            cmdMessage.setReceipt(toUser.getUsername());
            CmdMessageBody cmdMessageBody = new CmdMessageBody(INTO_GEO);
            cmdMessage.addBody(cmdMessageBody);
            EMChatManager.getInstance().sendMessage(cmdMessage, emCallBack);

            EMMessage message = EMMessage.createSendMessage(EMMessage.Type.LOCATION);
            BDLocation location = getCurrLocation();
            LocationMessageBody locBody = new LocationMessageBody(location.getAddrStr(), location.getLatitude(),
                    location.getLongitude());
            message.addBody(locBody);
            message.setReceipt(toUser.getUsername());
            EMChatManager.getInstance().sendMessage(message, emCallBack);

            EMMessage txtmessage = EMMessage.createSendMessage(EMMessage.Type.TXT);
            String content = getString(R.string.return_to_geofance) + ", " + String.format(getString(R.string.notifyItemMsg), location.getAddrStr());
            TextMessageBody txtBody = new TextMessageBody(content);
            txtmessage.addBody(txtBody);
            txtmessage.setReceipt(toUser.getUsername());
            EMChatManager.getInstance().sendMessage(txtmessage, emCallBack);
        }
    }


    public boolean isPointInGeofance(LatLng latlng) {
        return isPointInGeofance(latlng.latitude, latlng.longitude);
    }

    public boolean isPointInGeofance(double lat, double lng) {
        if (mGeofanceList == null || mGeofanceList.size() < 3) {
            return true;
        }
        GraphUtils.BmapPoint point = new GraphUtils.BmapPoint(lng, lat);
        ArrayList<GraphUtils.BmapPoint> geofanceList = new ArrayList<GraphUtils.BmapPoint>();
        for (LatLng latLng : mGeofanceList) {
            GraphUtils.BmapPoint bmapPoint = new GraphUtils.BmapPoint(latLng);
            geofanceList.add(bmapPoint);
        }
        return GraphUtils.isPointInPolygon(point,
                geofanceList.toArray(new GraphUtils.BmapPoint[geofanceList.size()]));
    }

//    public void createPoi(double latitude, double longitude, HttpResponseHandler handler) {
//        if (mGeotable == null) {
//            LOG("Geo table is null");
//            return;
//        }
//        LOG("createPoi " + "(" + latitude + ", " + longitude + ")");
//        CreatePoiReq req = new CreatePoiReq();
//        req.latitude = latitude;
//        req.longitude = longitude;
//        req.coord_type = 3;
//        req.geotable_id = (mGeotable.id);
//
//        Request request = new Request(LBSUrl.CREATE_POI);
//        request.setMethod(HttpMethod.Post);
//        request.setParamModel(req);
//
//        LOG("createPoi execute");
//
//        asyncExecutor.execute(request, handler);
//    }

    public void createPoi(double latitude, double longitude) {
//        if (mGeotable == null) {
//            LOG("Geo table is null");
//            return;
//        }
        LOG("createPoi " + "(" + latitude + ", " + longitude + ")");
//        CreatePoiReq req = new CreatePoiReq();
//        req.latitude = latitude;
//        req.longitude = longitude;
//        req.coord_type = 3;
//        req.geotable_id = mGeotable.id;
//
//        Request request = new Request(LBSUrl.CREATE_POI);
//        request.setMethod(HttpMethod.Post);
//        request.setParamModel(req);
//
//        LOG("createPoi execute");

        mLbsManager.createPoi(App.getInstance().getUserName(), latitude, longitude, 3, GEOTABLE_ID, responseHandler);
//        asyncExecutor.execute(request, responseHandler);
    }

//    public void createPoi(BDLocation bdLocation) {
//        if (mGeotable == null) {
//            LOG("Geo table is null");
//            return;
//        }
//        CreatePoiReq req = new CreatePoiReq();
//        req.latitude = bdLocation.getLatitude();
//        req.longitude = bdLocation.getLongitude();
//        req.address = bdLocation.getAddrStr();
//        req.coord_type = 3;
//        req.geotable_id = (mGeotable.id);
//
//        Request request = new Request(LBSUrl.CREATE_POI);
//        request.setMethod(HttpMethod.Post);
//        request.setParamModel(req);
//
//        LOG("createPoi execute");
//
//        mLbsManager.createPoi(bdLocation.getLatitude(),  bdLocation.getLongitude(), 3, mGeotable.id, responseHandler);
//
////        asyncExecutor.execute(request, responseHandler);
//    }

    public Callback<Respon> responseHandler = new Callback<Respon>() {
        @Override
        public void success(Respon respon, retrofit.client.Response response) {
            LOG(respon.toString());
            LOG(respon.status + " " + respon.message);
        }

        @Override
        public void failure(RetrofitError retrofitError) {

        }
    };

    public void setResponseHandler(Callback<Respon> handler) {
        this.responseHandler = handler;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return myBinder;
    }

    public void register(String name, String passwd) {
//        bmobUserAdapter.registerUser(name, passwd);
    }

    public BDLocation getCurrLocation() {
//        if (mLBSLocation != null) {
//
//            return mLBSLocation.getCurrlocation();
//        }

        if (mTraceService != null) {
            mTraceService.getBDLocation();
        }
        return null;
    }

    public void login(String name, String passwd) {
        logout();
//        listGeotable(name, passwd);
        requestLogin(name, passwd);
    }


    public void logout() {
//        if (mLBSLocation != null) {
//            mLBSLocation.stop();
//            if (mLBSLocation.getLocationLinkedList() != null) {
//                mLBSLocation.getLocationLinkedList().clear();
//            }
//        }

        if (mTraceService != null) {
            mTraceService.stopTrace(null);
        }

        mLoginState = false;
        isAdmin = false;
        clear();

//        if (App.DEBUG) {
//            getLbsManager().delPois(mUserName, new Callback<Respon>() {
//                @Override
//                public void success(Respon respon, retrofit.client.Response response) {
//                    LOG("del all pois success");
//                }
//
//                @Override
//                public void failure(RetrofitError retrofitError) {
//
//                }
//            });
//        }
    }

    public void setLoginCallback(LoginCallback ui) {
        this.mLoginCallback = ui;
    }

    public boolean isLogin() {
        return mLoginState;
    }

    public boolean isAdmin() {
        return isAdmin;
    }

    public ArrayList<Geotable> getAllGeotables() {
        return mAllGeotables;
    }

//    public void setAllGeotables(ArrayList<Geotable> AllGeotables) {
//        mAllGeotables.addAll(AllGeotables);
//        for (Geotable geotable : mAllGeotables) {
//            //update icon
//            GeotableItem geotableItem = mGeotableMap.get(geotable.id);
//            if (geotableItem == null && geotable.geotype != ADMIN_TABLE_TYPE) {
//                LOG("this is a new table , name " + geotable.name);
//                final String title = geotable.name;
//                final int id = geotable.id;
//                geotableItem = new GeotableItem(title);
//                geotableItem.setGeoId(id);
//                synchronized (GeotableMapLock) {
//                    mGeotableMap.put(id, geotableItem);
//                    mGeotableDB.addGeotable(geotableItem);
//                }
//
//                mLbsManager.getPoiList(id, new HttpResponseHandler() {
//                    @Override
//                    protected void onSuccess(Response res, HttpStatus status, NameValuePair[] headers) {
//                        PoiList respon = res.getObject(PoiList.class);
//                        if (respon != null && respon.status == 0) {
//                            GeotableItem item = mGeotableMap.get(id);
//                            if (item!= null && respon.pois != null && respon.pois.size() > 2) {
//                                boolean needUpdate = false;
//                                for (Poi p : respon.pois) {
//                                    if (p.getCoord_type() == LBSManager.PROP_TYPE) {
//                                        needUpdate = true;
//                                        if (p.getTitle().equals(GeotableDBHelper.POL_ID)) {
//                                            item.setPolId(p.getTags());
//                                        } else if (p.getTitle().equals(GeotableDBHelper.NAME)) {
//                                            item.setName(p.getTags());
//                                        } else if (p.getTitle().equals(GeotableDBHelper.UNIT)) {
//                                            item.setUnit(p.getTags());
//                                        } else if (p.getTitle().equals(GeotableDBHelper.IMEI)) {
//                                            item.setImei(p.getTags());
//                                        } else if (p.getTitle().equals(GeotableDBHelper.GROUP)) {
//                                            item.setGroup(p.getTags());
//                                        }
//                                    }
//                                }
//                                mGeotableItems.add(item);
//                                if (needUpdate) {
//                                    synchronized (GeotableMapLock) {
//                                        mGeotableMap.put(id, item);
//                                        mGeotableDB.update(item);
//
//                                        loadDataBaseTable();
//                                    }
//                                }
//                                callbackUiChange();
//                            }
//                        }
//                    }
//
//                    @Override
//                    protected void onFailure(Response res, HttpException e) {
//
//                    }
//                });
//            }
//
//        }
//    }


    public boolean isAdminPermisition() {
//        if (!isLogin() || !mGeotable.name.equals(ADMIN) || !isAdmin())
//            return false;
//        return true;
        return false;
    }

    public List<GeotableItem> getGeotableItems() {
        return this.mGeotableItems;
    }

    public HashMap<Integer, ArrayList<Poi>> getPoiListMap() {
        return mPoiListMap;
    }

    public void setGeofanceList(LinkedList<LatLng> list) {
        mGeofanceList.clear();
        mGeofanceList.addAll(list);
    }

    public LinkedList<LatLng> getGeofanceList() {
        return mGeofanceList;
    }

    public LinkedList<BDLocation> getLocationList() {
        return locationLinkedList;
    }

    public HashMap<String, ArrayList<GeotableItem>> getGroupMap() {
        return mGroupMap;
    }

    public ArrayList<String> getGroupList() {
        Iterator i = mGroupMap.keySet().iterator();
        ArrayList<String> groups = new ArrayList<String>();
        while(i.hasNext()) {
            Object o = i.next();
            String key = (String) o;
            groups.add(key);
        }
        return groups;
    }

    public void addUICallback(UICallback callback) {
        if (uiCallbacks == null) {
            uiCallbacks = new ArrayList<UICallback>();
        }
        uiCallbacks.add(callback);

//        mUICallback = callback;
    }

    public void removeUICallback(UICallback cb) {
        if (uiCallbacks != null) {
            uiCallbacks.remove(cb);
        }
    }

    public void callbackUiChange() {
        if (uiCallbacks == null) {
            return;
        }
        Timber.e("callback ui change");
        for (int i = 0; i < uiCallbacks.size(); i++) {
            UICallback callback = uiCallbacks.get(i);
            if (callback != null) {
                callback.onUpdateUserData();
            }
        }
    }

    public void getPoiList(String name, Callback<PoiList> cb) {
        mLbsManager.listPoi(GEOTABLE_ID, name, cb);
    }

    public void getPoiListByTime(String name, double min, double max, Callback<PoiList> cb) {
        mLbsManager.listPoiByTime(GEOTABLE_ID, name, min, max, cb);
    }

    public boolean isOutOfGeofance() {
        return isOutOfGeofance;
    }

    public int getGeoId() {
        return this.AdminGeoId;
    }

    public LBSManager getLbsManager() {
        return mLbsManager;
    }

    public class MyBinder extends Binder {

        public LBSClient getService(){
            return lbsClient;
        }
    }

    private MyBinder myBinder = new MyBinder();

    public void LOG(String msg) {
        Timber.d(msg);
    }

}
